package com.feiclub.subject.domain.handle.subject;


import com.feiclub.subject.common.enums.SubjectInfoTypeEnum;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 题目类型工厂
 *
 * @author: ChickenWing
 * @date: 2023/10/5
 */
@Component
@RequiredArgsConstructor
//这段代码定义了一个 SubjectTypeHandlerFactory 类，它是一个 Spring 组件 (@Component)，
// 并且通过 @RequiredArgsConstructor 注解来生成一个包含所有必需字段的构造函数。
public class SubjectTypeHandlerFactory implements InitializingBean {

    //subjectTypeHandlerList: 这是一个通过构造函数注入的 List<SubjectTypeHandler>，

    private final List<SubjectTypeHandler> subjectTypeHandlerList;
//    在 SubjectTypeHandlerFactory 类中，有一个成员变量 subjectTypeHandlerList，它的类型是 List<SubjectTypeHandler>。
//    这个列表是通过 Spring IoC 容器管理的，Spring 在启动时会扫描项目中的组件，
//    将实现了 SubjectTypeHandler 接口的类注册为 bean，并注入到 subjectTypeHandlerList 中。



// 其中 SubjectTypeHandler 是一个接口或者抽象类的实现类列表。它们的实现类或子类具体实现可能各不相同，
// 但都遵循了 SubjectTypeHandler 接口或者继承了 SubjectTypeHandler 类。




    //handlerMap: 这是一个 Map<SubjectInfoTypeEnum, SubjectTypeHandler> 类型的实例变量，
    // 用来将 SubjectInfoTypeEnum 枚举值与对应的 SubjectTypeHandler 实例关联起来。
    private Map<SubjectInfoTypeEnum, SubjectTypeHandler> handlerMap = new HashMap<>();


    //getHandler(int subjectType): 这个方法根据传入的 subjectType 参数获取相应的 SubjectTypeHandler。
    // 例如新增题目   在使用工厂时  对象里会带有题目类型的字段 1 2 3 4 等
    public SubjectTypeHandler getHandler(int subjectType) {
        // 它通过调用 SubjectInfoTypeEnum.getByCode(subjectType) 方法来获取 SubjectInfoTypeEnum 枚举值，
        SubjectInfoTypeEnum subjectInfoTypeEnum = SubjectInfoTypeEnum.getByCode(subjectType);
        // 然后从 handlerMap 中取得对应的 SubjectTypeHandler 实例并返回。
        return handlerMap.get(subjectInfoTypeEnum);
    }

    //afterPropertiesSet(): 这是 InitializingBean 接口中的方法，
    // 在 Spring 容器设置了所有的 bean 属性之后自动调用。在这个方法中，它遍历 subjectTypeHandlerList，
    // 并将每个 SubjectTypeHandler 实例与其对应的 SubjectInfoTypeEnum 枚举值放入 handlerMap 中，建立映射关系。
//Purpose: SubjectTypeHandlerFactory 的主要目的是根据 subjectType 获取相应的 SubjectTypeHandler 实例，以处理特定类型的主题信息。
//
    @Override
    public void afterPropertiesSet() throws Exception {
        for (SubjectTypeHandler subjectTypeHandler : subjectTypeHandlerList) {
            handlerMap.put(subjectTypeHandler.getHandlerType(), subjectTypeHandler);
        }
    }

}




//

//Functionality:
//
//在 Spring 容器初始化时，通过 afterPropertiesSet() 方法将所有的 SubjectTypeHandler 实例按照其 SubjectInfoTypeEnum 注册到 handlerMap 中。
//getHandler(int subjectType) 方法允许客户端代码通过传入 subjectType 来获取相应的 SubjectTypeHandler，以执行具体的处理逻辑。
//Example Usage Scenario:
//假设有多个不同类型的主题信息需要处理，每种类型有不同的处理逻辑，可以通过 SubjectTypeHandler 接口的多个实现类来分别处理。SubjectTypeHandlerFactory 可以根据具体的主题类型动态地选择正确的处理器，并执行相应的业务逻辑。
//
//这种设计支持了解耦和可扩展性，允许通过添加新的 SubjectTypeHandler 实现类来支持新的主题类型，而无需修改 SubjectTypeHandlerFactory 的代码。
